/*
 * Lop ho tro hien thi doi tuong vung Polygon
 */
viettel.Polygon = function (opts) {
    viettel.MVCObject.call(this);

    this.CLASSNAME = "viettel.Polygon";

    var that = this;
    var options = new viettel.PolygonOptions();
    var vectorLayer = null;                     // Layer chua doi tuong
    var olPolygon = null;                       // Doi tuong tuong ung OpenLayers
    var polygonEditor = null;                      // Ho tro chinh sua doi tuong Polygon

    // Thuc hien tao doi tuong Polygon
    var updatePolygon = function () {
        if (options.map == null) return;
        if (options.paths == null) return;

        vectorLayer = options.map.getVectorDefault();

        olPolygon = new OpenLayers.Feature.Vector();
        olPolygon.vtObject = that;

        var polygon = new OpenLayers.Geometry.Polygon();
        olPolygon.geometry = polygon;
        polygon.components = [];
        vectorLayer.addFeatures(olPolygon);

        // Cap nhat thuoc tinh cho doi tuong
        updateStyle(false);
        updateClickable();
        updatePaths(true);
        updateDraggable();
        updateEditable();
    }

    // Cap nhat style
    var updateStyle = function (isDrawn) {
        olPolygon.style = options.getStyle();
        if (polygonEditor != null) {
            polygonEditor.display(options.visible);
        }
        if (isDrawn) {
            reDrawPolygon();
        }
    }

    // Cap nhat che do clickable cho Polygon
    var updateClickable = function () {
        if (options.clickable) {
            olPolygon.style.cursor = "pointer";
        }
        else {
            olPolygon.style.cursor = "";
        }
    }

    // Cap nhat toa do cho paths cua Polygon (Dang MVCArray)
    var updatePolyPaths = function (paths, baseLatLng, currentLatLng) {
        var latSpacing = currentLatLng.lat() - baseLatLng.lat();
        var lngSpacing = currentLatLng.lng() - baseLatLng.lng();
        var num = paths.getLength();
        for (var i = 0; i < num; i++) {
            var path = paths.getAt(i);
            var length = path.getLength();
            for (var j = 0; j < length; j++) {
                var pt = path.getAt(j);
                pt.offset(latSpacing, lngSpacing);
            }
        }
    }

    // Ham dieu khien su kien Mousedown
    var mousedownHandler = function (evt) {
        // Tinh toan cac diem goc
        var mapOffsetLeft = options.map.getMapConfig().mapPosition.left;
        var mapOffsetTop = options.map.getMapConfig().mapPosition.top;
        var baseLatLng = new viettel.LatLng(evt.latLng.lat(), evt.latLng.lng());

        var startX = parseInt(evt.pageX,10);
        var startY = parseInt(evt.pageY,10);
        // Thiet lap mot so bien
        var isDragging = false
        var isMouseDown = true;

        var oldMapDraggable = options.map.getOptions().draggable;
        options.map.setOptions({
            draggable: false
        });

        // Bat su kien mousemove cua document
        var mousemove = viettel.Events.addDomListener(document, "mousemove", function (evt) {
            if (!isMouseDown) return;
            if (startX == parseInt(evt.pageX,10) && startY == parseInt(evt.pageY,10)) return;
            startX = parseInt(evt.pageX,10);
            startY = parseInt(evt.pageY,10);
            var x = evt.pageX - mapOffsetLeft;
            var y = evt.pageY - mapOffsetTop;
            var mouseEvent = new viettel.MouseEvent(evt, options.map, {
                x: x,
                y: y
            }, that);
            updatePolyPaths(options.paths, baseLatLng, mouseEvent.latLng);
            baseLatLng = mouseEvent.latLng;
            updatePaths(true);
            if (!isDragging) {
                // Tam thoi loai bo mot so su kien tren map
                //viettel.TmpEventRemover.removeAllEvents(viettel.VTObjType.Map);
                //viettel.TmpEventRemover.removeAllEvents(viettel.VTObjType.Vector);
                isDragging = true;
                viettel.Events.trigger(that, 'dragstart', mouseEvent);
            }
            else {
                viettel.Events.trigger(that, 'drag', mouseEvent);
            }
        });

        // Bat su kien mouseup cua document
        var mouseup = viettel.Events.addDomListener(document, "mouseup", function (evt) {
            if (isMouseDown) {
                isMouseDown = false;
                options.map.setOptions({
                    draggable: oldMapDraggable
                });

                var x = evt.pageX - mapOffsetLeft;
                var y = evt.pageY - mapOffsetTop;

                viettel.Events.removeListener(mousemove);
                viettel.Events.removeListener(mouseup);
                if (isDragging) {
                    isDragging = false;

                    // Khoi phuc lai cac su kien
                    //setTimeout(function() {
                    //	viettel.TmpEventRemover.restoreAllEvents(viettel.VTObjType.Map);
                    //	viettel.TmpEventRemover.restoreAllEvents(viettel.VTObjType.Vector);
                    //}, 20);

                    // Cap nhat toa do va day su kien ra
                    var mouseEvent = new viettel.MouseEvent(evt, options.map, {
                        x: x,
                        y: y
                    }, that);
                    updatePolyPaths(options.paths, baseLatLng, mouseEvent.latLng);
                    updatePaths(true);
                    viettel.Events.trigger(that, 'dragend', mouseEvent);
                    viettel.Events.trigger(that, "paths_changed");
                }
            }
        });
    }

    // Cap nhat che do draggable
    var mouseDownListener = null;
    var updateDraggable = function () {
        if (mouseDownListener != null) {
            viettel.Events.removeListener(mouseDownListener);
            mouseDownListener = null;
        }
        if (options.draggable) {
            mouseDownListener = viettel.Events.addListener(that, "mousedown", mousedownHandler);
        }
    }

    // Cap nhat che do editable
    var updateEditable = function () {
        if (options.editable) {
            if (polygonEditor == null) {
                polygonEditor = new viettel.PolygonEditor(that);
                polygonEditor.activate();
            }
        }
        else {
            if (polygonEditor != null) {
                polygonEditor.deactivate();
                polygonEditor = null;
            }
        }
    }

    // Cap nhat path cho doi tuong
    var updatePaths = function (isDrawn) {
        if (olPolygon == null || vectorLayer == null) return;

        olPolygon.geometry.components = [];
        for (var i = 0; i < options.paths.getLength() ; i++) {
            olPolygon.geometry.addComponents([options.paths.getAt(i)._getLinearRing()]);
        }

        if (polygonEditor != null) {
            polygonEditor.updateGeography();
        }

        if (isDrawn) {
            reDrawPolygon();
        }
    }

    // Ve lai doi tuong Polygon
    var reDrawPolygon = function () {
        vectorLayer.drawFeature(olPolygon, olPolygon.style);
    }

    // Kiem tra doi tuong Polygon da duoc tao chua?
    var isPolygonCreated = function () {
        return (olPolygon != null);
    }

    this.getMap = function () {
        return options.map;
    }
    this.setMap = function (_map) {
        this.setOptions({
            map: _map
        });
    }

    this.getPath = function () {
        if (options.paths == null || options.paths.getLength() == 0) return null;
        return options.paths.getAt(0);
    }
    this.getPaths = function () {
        return options.paths;
    }
    this.setPath = function (path) {
        this.setOptions({
            paths: path
        });
        viettel.Events.trigger(that, "paths_changed");
    }
    this.setPaths = function (paths) {
        this.setOptions({
            paths: paths
        });
        viettel.Events.trigger(that, "paths_changed");
    }

    this.getClickable = function () {
        return options.clickable;
    }
    this.setClickable = function (clickable) {
        this.setOptions({
            clickable: clickable
        });
    }

    this.setVisible = function (visible) {
        this.setOptions({
            visible: visible
        });
    }
    this.getVisible = function () {
        return options.visible;
    }

    this.setZIndex = function (zIndex) {
        this.setOptions({
            zIndex: zIndex
        });
    }
    this.getZIndex = function () {
        return options.zIndex;
    }

    this.setDraggable = function (draggable) {
        this.setOptions({
            draggable: draggable
        });
    }
    this.getDraggable = function () {
        return options.draggable;
    }

    this.setEditable = function (editable) {
        this.setOptions({
            editable: editable
        });
    }
    this.getEditable = function () {
        return options.editable;
    }

    // Kiem tra polygon co chua diem khong
    this.containPoint = function (point) {
        return viettel.GeometryUtil.checkPointInPolygon(point, this.getPath().getArray())
    }

    // Lay boundary doi tuong
    this.getBounds = function () {
        return options.getBounds();
    }

    // Tinh chu vi doi tuong theo don vi meter
    this.getPerimeter = function () {
        var perimeter = 0.0;
        var paths = this.getPaths();
        for (var i = 0; i < paths.getLength() ; i++) {
            perimeter += viettel.GeometryUtil.getLength(paths.getAt(i));
        }
        return perimeter;
    }

    // Tinh dien tich doi tuong theo don vi meter
    this.getArea = function () {
        return olPolygon.geometry.getGeodesicArea(mapProjection);
    }

    this.getOptions = function () {
        return options;
    }
    this.setOptions = function (opts) {
        if (opts == null) return;

        // Xu ly cap nhat thuoc tinh path/paths
        if (opts.path != null && opts.paths == null) {
            opts.paths = opts.path;             // De ho tro cac phien ban cu
        }
        if (options.updatePaths(opts.paths)) {
            if (isPolygonCreated()) {
                updatePaths(true);
            }
        }

        if (VTObjChecker.isBoolean(opts.clickable)) {
            options.clickable = opts.clickable;
            if (isPolygonCreated()) {
                updateClickable();
            }
        }

        if (VTObjChecker.isBoolean(opts.draggable)) {
            options.draggable = opts.draggable;
            if (isPolygonCreated()) {
                updateDraggable();
            }
        }

        if (VTObjChecker.isBoolean(opts.editable)) {
            options.editable = opts.editable;
            if (isPolygonCreated()) {
                updateEditable();
            }
        }

        var styleChanged = false;
        if (VTObjChecker.isBoolean(opts.visible)) {
            options.visible = opts.visible;
            styleChanged = true;
        }
        if (VTObjChecker.isString(opts.fillColor)) {
            options.fillColor = opts.fillColor;
            styleChanged = true;
        }
        if (VTObjChecker.isNumber(opts.fillOpacity)) {
            options.fillOpacity = opts.fillOpacity;
            styleChanged = true;
        }
        if (VTObjChecker.isString(opts.strokeColor)) {
            options.strokeColor = opts.strokeColor;
            styleChanged = true;
        }
        if (VTObjChecker.isNumber(opts.strokeOpacity)) {
            options.strokeOpacity = opts.strokeOpacity;
            styleChanged = true;
        }
        if (VTObjChecker.isNumber(opts.strokeWeight)) {
            options.strokeWeight = opts.strokeWeight;
            styleChanged = true;
        }
        if (VTObjChecker.isNumber(opts.zIndex)) {
            options.zIndex = opts.zIndex;
            styleChanged = true;
        }
        if (styleChanged && isPolygonCreated()) {
            updateStyle(true);
        }

        if (VTObjChecker.isMapObj(opts.map)) {
            options.map = opts.map;
            updatePolygon();
        }
        else if (typeof (opts.map) == "undefined") {
            // Phai kiem tra truoc, neu la undefined se xu ly dac biet
            // Truong hop ma co du thong tin can tao gia tri
            if (options.map != null && options.paths != null && !isPolygonCreated()) {
                updatePolygon();
            }
        }
        else if (opts.map == null) {
            options.map = null;
            if (mouseDownListener != null) {
                viettel.Events.removeListener(mouseDownListener);
                mouseDownListener = null;
            }
            if (olPolygon != null) {
                if (vectorLayer != null) {
                    vectorLayer.removeFeatures([olPolygon]);
                }
                if (polygonEditor != null) {
                    polygonEditor.deactivate();
                    polygonEditor = null;
                }
                olPolygon.destroy();
                olPolygon = null;
            }
        }
    }

    // Lay doi tuong OpenLayer tuong ung
    this.getOriginalObj = function () {
        return olPolygon;
    }

    var init = function () {
        that.setOptions(opts);
    }
    init();

}
viettel.Polygon.prototype = new viettel.MVCObject();
viettel.Polygon.prototype.constructor = viettel.Polygon;